% addpath R/R_LIBS/linux/library/R.matlab/misc/
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % MATLAB version-dependent setup % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Identify major version of Matlab MatlabServer_tmp_hasMajor = eval('length(regexp(version, ''^[0-9]'')) ~= 0', '0'); if (MatlabServer_tmp_hasMajor) MatlabServer_tmp_verParts = sscanf(version, '%d.'); MatlabServer_tmp_verMajor = MatlabServer_tmp_verParts(1); clear MatlabServer_tmp_verParts; else MatlabServer_tmp_verMajor = -1; end clear MatlabServer_tmp_hasMajor;
if (MatlabServer_tmp_verMajor < 6) % Java is not available/supported error('MATLAB v5.x and below is not supported.'); elseif (MatlabServer_tmp_verMajor == 6) disp('MATLAB v6.x detected.'); % Default save option MatlabServer_saveOption = ''; % In MATLAB v6 only the static Java CLASSPATH is supported. It is % specified by a 'classpath.txt' file. The default one can be found % by which('classpath.txt'). If a 'classpath.txt' exists in the % current(!) directory (that MATLAB is started from), it *replaces* % the global one. Thus, it is not possible to add additional paths; % the global ones has to be copied to the local 'classpath.txt' file. % % To do the above automatically from R, does not seem to be an option. else disp('MATLAB v7.x or higher detected.'); % MATLAB v7 and above saves compressed files, which is not recognized % by R.matlab's readMat(); force saving in old format. MatlabServer_saveOption = '-V6'; disp('Saving with option -V6.');
% In MATLAB v7 and above both static and dynamic Java CLASSPATH:s exist. % Using dynamic ones, it is possible to add the file % InputStreamByteWrapper.class to CLASSPATH, given it is % in the same directory as this script. javaaddpath({fileparts(which('MatlabServer'))}); disp('Added InputStreamByteWrapper to dynamic Java CLASSPATH.'); end clear MatlabServer_tmp_verMajor;
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Import Java classes % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - import java.io.*; import java.net.*;
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % If an old MATLAB server is running, close it % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % If a server object exists from a previous run, close it. if (exist('MatlabServer_server')) close(MatlabServer_server); clear MatlabServer_server; end
% If an input stream exists from a previous run, close it. if (exist('MatlabServer_is')) close(MatlabServer_is); clear MatlabServer_is; end
% If an output stream exists from a previous run, close it. if (exist('MatlabServer_os')) close(MatlabServer_os); clear MatlabServer_os; end
fprintf(1, '----------------------\n'); fprintf(1, 'MATLAB server started!\n'); fprintf(1, '----------------------\n');
fprintf(1, 'MATLAB working directory: %s\n', pwd);
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Initiate server socket to which clients may connect % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MatlabServer_port = getenv('MATLABSERVER_PORT'); if (length(MatlabServer_port) > 0) MatlabServer_port = str2num(MatlabServer_port); else % Try to open a server socket on port 9999 MatlabServer_port = 9999; end
% Ports 1-1023 are reserved for the Internet Assigned Numbers Authority. % Ports 49152-65535 are dynamic ports for the OS. [3] if (MatlabServer_port < 1023 | MatlabServer_port > 65535) error('Cannot not open connection. Port (''MATLABSERVER_PORT'') is out of range [1023,65535]: %d', MatlabServer_port); end
fprintf(1, 'Trying to open server socket (port %d)...', MatlabServer_port); MatlabServer_server = java.net.ServerSocket(MatlabServer_port); fprintf(1, 'done.\n');
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Wait for client to connect % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Create a socket object from the ServerSocket to listen and accept % connections. % Open input and output streams
% Wait for the client to connect fprintf(1, 'Waiting for client to connect (port %d)...', MatlabServer_port); MatlabServer_clientSocket = accept(MatlabServer_server); fprintf(1, 'connected.\n');
% ...client connected. MatlabServer_is = java.io.DataInputStream(getInputStream(MatlabServer_clientSocket)); MatlabServer_os = java.io.DataOutputStream(getOutputStream(MatlabServer_clientSocket));
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % The MATLAB server state machine % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Commands MatlabServer_commands = {'eval', 'send', 'receive', 'send-remote', 'receive-remote', 'echo', 'evalc'};
MatlabServer_lasterr = []; MatlabServer_variables = [];
% As long as we receive data, echo that data back to the client. MatlabServer_state = 0; while (MatlabServer_state >= 0), if (MatlabServer_state == 0) MatlabServer_tmp_cmd = readByte(MatlabServer_is); fprintf(1, 'Received cmd: %d\n', MatlabServer_tmp_cmd); if (MatlabServer_tmp_cmd < -1 | MatlabServer_tmp_cmd > length(MatlabServer_commands)) fprintf(1, 'Unknown command code: %d\n', MatlabServer_tmp_cmd); else MatlabServer_state = MatlabServer_tmp_cmd; end clear MatlabServer_tmp_cmd;
%------------------- % 'evalc' %------------------- elseif (MatlabServer_state == strmatch('evalc', MatlabServer_commands, 'exact')) MatlabServer_tmp_bfr = char(readUTF(MatlabServer_is)); fprintf(1, '"evalc" string: "%s"\n', MatlabServer_tmp_bfr); try MatlabServer_tmp_bfr = sprintf(MatlabServer_tmp_bfr); MatlabServer_tmp_result = evalc(MatlabServer_tmp_bfr); writeByte(MatlabServer_os, 0); fprintf(1, 'Sent byte: %d\n', 0); writeUTF(MatlabServer_os, MatlabServer_tmp_result); fprintf(1, 'Sent UTF: %s\n', MatlabServer_tmp_result); flush(MatlabServer_os); clear MatlabServer_tmp_result; catch MatlabServer_lasterr = sprintf('Failed to evaluate expression ''%s''.', MatlabServer_tmp_bfr); fprintf(1, 'EvaluationException: %s\n', MatlabServer_lasterr); writeByte(MatlabServer_os, -1); fprintf(1, 'Sent byte: %d\n', -1); writeUTF(MatlabServer_os, MatlabServer_lasterr); fprintf(1, 'Sent UTF: %s\n', MatlabServer_lasterr); flush(MatlabServer_os); end flush(MatlabServer_os); MatlabServer_state = 0; clear MatlabServer_tmp_bfr;
%------------------- % 'eval' %------------------- elseif (MatlabServer_state == strmatch('eval', MatlabServer_commands, 'exact')) MatlabServer_tmp_bfr = char(readUTF(MatlabServer_is)); fprintf(1, '"eval" string: "%s"\n', MatlabServer_tmp_bfr); try eval(MatlabServer_tmp_bfr); writeByte(MatlabServer_os, 0); fprintf(1, 'Sent byte: %d\n', 0); flush(MatlabServer_os); catch MatlabServer_lasterr = sprintf('Failed to evaluate expression ''%s''.', MatlabServer_tmp_bfr); fprintf(1, 'EvaluationException: %s\n', MatlabServer_lasterr); writeByte(MatlabServer_os, -1); fprintf(1, 'Sent byte: %d\n', -1); writeUTF(MatlabServer_os, MatlabServer_lasterr); fprintf(1, 'Sent UTF: %s\n', MatlabServer_lasterr); flush(MatlabServer_os); end flush(MatlabServer_os); MatlabServer_state = 0; clear MatlabServer_tmp_bfr; %------------------- % 'send' %------------------- elseif (MatlabServer_state == strmatch('send', MatlabServer_commands, 'exact')) MatlabServer_tmp_tmpname = sprintf('%s_%d.mat', tempname, MatlabServer_port); MatlabServer_tmp_expr = sprintf('save(MatlabServer_tmp_tmpname, ''%s''', MatlabServer_saveOption); MatlabServer_tmp_ok = 1; for MatlabServer_tmp_k=1:length(MatlabServer_variables), MatlabServer_tmp_variable = MatlabServer_variables{MatlabServer_tmp_k}; if (exist(MatlabServer_tmp_variable) ~= 1) MatlabServer_lasterr = sprintf('Variable ''%s'' not found.', MatlabServer_tmp_variable); disp(MatlabServer_lasterr); MatlabServer_tmp_ok = 0; break; end; MatlabServer_tmp_expr = sprintf('%s, ''%s''', MatlabServer_tmp_expr, MatlabServer_tmp_variable); end;
MatlabServer_tmp_expr = sprintf('%s)', MatlabServer_tmp_expr); if (~MatlabServer_tmp_ok) writeInt(MatlabServer_os, -1); writeUTF(MatlabServer_os, MatlabServer_lasterr); else disp(MatlabServer_tmp_expr); eval(MatlabServer_tmp_expr); writeInt(MatlabServer_os, 0); % Here anything but -1 means "success" writeUTF(MatlabServer_os, MatlabServer_tmp_tmpname); end MatlabServer_tmp_answer = readByte(MatlabServer_is); fprintf('answer=%d\n', MatlabServer_tmp_answer); MatlabServer_state = 0; clear MatlabServer_tmp_name MatlabServer_tmp_expr MatlabServer_tmp_ok MatlabServer_tmp_answer;
%------------------- % 'send-remote' %------------------- elseif (MatlabServer_state == strmatch('send-remote', MatlabServer_commands, 'exact')) MatlabServer_tmp_tmpname = sprintf('%s_%d.mat', tempname, MatlabServer_port); MatlabServer_tmp_expr = sprintf('save(MatlabServer_tmp_tmpname, ''%s''', MatlabServer_saveOption); MatlabServer_tmp_ok = 1; for MatlabServer_tmp_k=1:length(MatlabServer_variables), MatlabServer_tmp_variable = MatlabServer_variables{MatlabServer_tmp_k}; if (exist(MatlabServer_tmp_variable) ~= 1) MatlabServer_lasterr = sprintf('Variable ''%s'' not found.', MatlabServer_tmp_variable); disp(MatlabServer_lasterr); MatlabServer_tmp_ok = 0; break; end; MatlabServer_tmp_expr = sprintf('%s, ''%s''', MatlabServer_tmp_expr, MatlabServer_tmp_variable); end; clear MatlabServer_tmp_k MatlabServer_tmp_variable;
MatlabServer_tmp_expr = sprintf('%s)', MatlabServer_tmp_expr); if (~MatlabServer_tmp_ok) writeInt(MatlabServer_os, -1); writeUTF(MatlabServer_os, MatlabServer_lasterr); else disp(MatlabServer_tmp_expr); eval(MatlabServer_tmp_expr); MatlabServer_tmp_file = java.io.File(MatlabServer_tmp_tmpname); MatlabServer_tmp_maxLength = length(MatlabServer_tmp_file); clear MatlabServer_tmp_file; writeInt(MatlabServer_os, MatlabServer_tmp_maxLength); % Here anything but -1 means "success" fprintf(1, 'Send int: %d (maxLength)\n', MatlabServer_tmp_maxLength); MatlabServer_tmp_fid = fopen(MatlabServer_tmp_tmpname, 'r'); MatlabServer_tmp_count = 1; while (MatlabServer_tmp_count ~= 0) [MatlabServer_tmp_bfr, MatlabServer_tmp_count] = fread(MatlabServer_tmp_fid, 65536, 'int8'); if (MatlabServer_tmp_count > 0) write(MatlabServer_os, MatlabServer_tmp_bfr); end; end; fclose(MatlabServer_tmp_fid); fprintf(1, 'Send buffer: %d bytes.\n', MatlabServer_tmp_maxLength); delete(MatlabServer_tmp_tmpname); clear MatlabServer_tmp_bfr MatlabServer_tmp_count MatlabServer_tmp_maxLength MatlabServer_tmp_fid MatlabServer_tmp_tmpname; end flush(MatlabServer_os); MatlabServer_tmp_answer = readByte(MatlabServer_is); fprintf('answer=%d\n', MatlabServer_tmp_answer); MatlabServer_state = 0; clear MatlabServer_tmp_name MatlabServer_tmp_expr MatlabServer_tmp_ok MatlabServer_tmp_answer;
%------------------- % 'receive-remote' %------------------- elseif (MatlabServer_state == strmatch('receive-remote', MatlabServer_commands, 'exact')) MatlabServer_tmp_len = readInt(MatlabServer_is); fprintf(1, 'Will read MAT file structure of length: %d bytes.\n', MatlabServer_tmp_len);
MatlabServer_tmp_reader = InputStreamByteWrapper(4096); MatlabServer_tmp_bfr = []; MatlabServer_tmp_count = 1; while (MatlabServer_tmp_len > 0 & MatlabServer_tmp_count > 0) MatlabServer_tmp_count = MatlabServer_tmp_reader.read(MatlabServer_is, min(4096, MatlabServer_tmp_len)); if (MatlabServer_tmp_count > 0) MatlabServer_tmp_bfr = [MatlabServer_tmp_bfr; MatlabServer_tmp_reader.bfr(1:MatlabServer_tmp_count)]; MatlabServer_tmp_len = MatlabServer_tmp_len - MatlabServer_tmp_count; end; end;
clear MatlabServer_tmp_reader MatlabServer_tmp_count MatlabServer_tmp_len;
MatlabServer_tmp_tmpfile = sprintf('%s_%d.mat', tempname, MatlabServer_port); MatlabServer_tmp_fh = fopen(MatlabServer_tmp_tmpfile, 'wb'); fwrite(MatlabServer_tmp_fh, MatlabServer_tmp_bfr, 'int8'); fclose(MatlabServer_tmp_fh);
clear MatlabServer_tmp_fh MatlabServer_tmp_bfr; load(MatlabServer_tmp_tmpfile); delete(MatlabServer_tmp_tmpfile); clear MatlabServer_tmp_tmpfile; writeByte(MatlabServer_os, 0);
MatlabServer_state = 0; %------------------- % 'receive' %------------------- elseif (MatlabServer_state == strmatch('receive', MatlabServer_commands, 'exact')) MatlabServer_tmp_filename = char(readUTF(MatlabServer_is)); fprintf(1, 'Will read MAT file: "%s"\n', MatlabServer_tmp_filename); load(MatlabServer_tmp_filename); clear MatlabServer_tmp_filename; writeByte(MatlabServer_os, 0); MatlabServer_state = 0; clear MatlabServer_tmp_filename; end end
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Shutting down the MATLAB server % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fprintf(1, '-----------------------\n'); fprintf(1, 'MATLAB server shutdown!\n'); fprintf(1, '-----------------------\n'); writeByte(MatlabServer_os, 0); close(MatlabServer_os); close(MatlabServer_is); close(MatlabServer_server); quit;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% HISTORY:
% 2015-09-11 [v3.3.0]
% o Now temporary files use format
remote=TRUE
).import java.io.*;
/********************************************************************* % Compile from within MATLAB with: % !javac InputStreamByteWrapper.java
% MATLAB example that reads a file using Java code and writes it % back to a temporary file using MATLAB code. Finally the contents % of the new file is displayed.
reader = InputStreamByteWrapper; % Default buffer size is 4096 bytes.
in = java.io.FileInputStream('InputStreamByteWrapper.java');
bfr = []; len = 1; while (len > 0) len = reader.read(in, 16); % Read 16 bytes at the time (offset=0). if (len > 0) bfr = [bfr; reader.bfr(1:len)]; % Add bytes to my MATLAB buffer. end end
close(in); clear in, reader;
disp(bfr');
tmpfile = tempname; fh = fopen(tmpfile, 'wb'); fwrite(fh, bfr, 'char'); fclose(fh);
type(tmpfile); *********************************************************************/ public class InputStreamByteWrapper { public static byte[] bfr = null;
public InputStreamByteWrapper(int capasity) { bfr = new byte[capasity]; }
public InputStreamByteWrapper() { this(4096); }
public int read(InputStream in, int offset, int length) throws IOException { return in.read(bfr, offset, length); }
public int read(InputStream in, int length) throws IOException { return read(in, 0, length); }
public int read(InputStream in) throws IOException { return in.read(bfr); } }
/********************************************************************* HISTORY: 2013-07-11 o Updated comments to use 'MATLAB' instead of 'Matlab'. 2002-09-02 [or maybe a little bit earlier] o Created. *********************************************************************/